#include <glm/gtc/noise.hpp>
#include "voxelchunk.hpp"

uint32_t vx::VoxelChunk::SIZE = 16;
uint32_t vx::VoxelChunk::HEIGHT = 16;

vx::VoxelChunk::VoxelChunk(const glm::ivec2& position)
{
    _position = position;

    const uint32_t volume = getVolume();
    Voxel* rawVoxels = new Voxel[volume];
    _voxels = std::shared_ptr<Voxel[]>(rawVoxels);

    for (int32_t y = 0; y < VoxelChunk::HEIGHT; y++)
    {
        for (int32_t z = 0; z < VoxelChunk::SIZE; z++)
        {
            for (int32_t x = 0; x < VoxelChunk::SIZE; x++)
            {
                const int32_t realX = x + position.x * SIZE;
                const int32_t realZ = z + position.y * SIZE;

                const uint32_t index = getVoxelIndexAt(x, y, z);
                uint16_t id = 0;
                if (y / 5.0f < std::sin(realX * 0.7f) * 0.5f + 0.5f)
                {
                    id = 1;
                }
                _voxels[index] = id;
            }
        }
    }
}

vx::VoxelChunk::~VoxelChunk()
{
}

glm::ivec2 vx::VoxelChunk::getPosition() const
{
    return _position;
}

vx::Voxel vx::VoxelChunk::getVoxelAt(const uint32_t x, const uint32_t y, const uint32_t z) const
{
    const uint32_t index = getVoxelIndexAt(x, y, z);
    return _voxels[index];
}

uint32_t vx::VoxelChunk::getVolume()
{
    return SIZE * SIZE * HEIGHT;
}

uint32_t vx::VoxelChunk::getVoxelIndexAt(const uint32_t x, const uint32_t y, const uint32_t z) const
{
    return (y * SIZE + z) * SIZE + x;
}
